﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Physis.Client.Controllers {

    public class SecurityManagementController : ApplicationController {

        protected override void Initialize (System.Web.Routing.RequestContext requestContext) {

            base.Initialize (requestContext);

            if (!applicationModel.Application.Session.HasEnterprisePermission (Physis.Security.Permissions.Enterprise.SecurityManagement)) {

                Response.Redirect ("~/PermissionDenied", true);

            }

            return;

        }



        #region Role

        [HttpGet]
        public ActionResult EnterpriseRole (Int64 id) {

            Models.Configuration.RoleModel model = new Models.Configuration.RoleModel (id);

            model.ForEnteprise = true;

            return View ("~/Views/Configuration/Role.cshtml", model);

        }

        [HttpGet]
        public ActionResult EnvironmentRole (Int64 id) {

            Models.Configuration.RoleModel model = new Models.Configuration.RoleModel (id);

            return View ("~/Views/Configuration/Role.cshtml", model);

        }

        [HttpGet]
        public JsonResult RolesByEnvironment (Int64 environmentId) {

            JsonResponses.ObjectCollectionResponse response = new JsonResponses.ObjectCollectionResponse ();


            List<Security.Role> roles = applicationModel.Application.Security.RolesByEnvironment (environmentId);

            response.Objects = new List<Object> (roles);


            return Json (response, JsonRequestBehavior.AllowGet);

        }

        [HttpGet]
        public ActionResult Role (Int64 id) {

            Models.Configuration.RoleModel model = new Models.Configuration.RoleModel (id);

            return View ("~/Views/Configuration/Role.cshtml", model);

        }

        [HttpPost]
        public JsonResult RoleSave () {

            JsonResponses.SaveResponse response = new JsonResponses.SaveResponse ();

            Models.Configuration.RoleModel model = new Models.Configuration.RoleModel (Request.Form);

            response.Result = model.Role.Save ();

            response.Id = model.Role.Id;

            response.SetException (model.Application.LastException);

            return Json (response, JsonRequestBehavior.DenyGet);

        }


        private JsonResult RoleDelete (Int64 id) {

            JsonResponses.BooleanResponse response = new JsonResponses.BooleanResponse ();

            Models.Configuration.RoleModel model = new Models.Configuration.RoleModel (id);

            response.Result = model.Role.Delete ();

            response.SetException (model.Application.LastException);

            return Json (response, JsonRequestBehavior.DenyGet);

        }

        [HttpDelete]
        public JsonResult EnterpriseRoleDelete (Int64 id) { return RoleDelete (id); }

        [HttpDelete]
        public JsonResult EnvironmentRoleDelete (Int64 id) { return RoleDelete (id); }

        [HttpPost]
        public JsonResult PermissionsCalculatedForRolesByEnvironment (Int64 environmentId) {

            JsonResponses.ObjectCollectionResponse response = new JsonResponses.ObjectCollectionResponse ();


            // READ THE SUBMITTED ROLES FROM THE FORM (ROLE MEMBERSHIP) 

            String jsonRoleMembership = Data.Readers.FormReader.StringFromForm (Request.Form, "Role.Membership");

            List<Security.RoleMembership> roleMembership = new List<Security.RoleMembership> (); // INITIALIZZE SO THAT WE CAN GET THE TYPE IN THE NEXT STATEMENT

            roleMembership = (List<Security.RoleMembership>)new System.Web.Script.Serialization.JavaScriptSerializer ().Deserialize (jsonRoleMembership, roleMembership.GetType ());


            // UPDATE THE APPLICATION REFERENCE AND FILTER OUT THE SPECIFIC ENVIRONMENT ROLES 

            roleMembership.ForEach (current => current.Application = applicationModel.Application);

            List<Security.Role> roles = (from currentRoleMembership in roleMembership

                                         where (currentRoleMembership.Role.EnvironmentId == environmentId)

                                         select currentRoleMembership.Role).Distinct ().ToList ();

            // GET THE CALCAULATED PERMISSIONS FOR THE ROLES

            String permissionPrefix = ((environmentId == 0) ? "Enterprise." : "Environment.");

            response.Objects = applicationModel.Application.Security.PermissionsCalculatedForRoles (permissionPrefix, roles);


            return Json (response, JsonRequestBehavior.DenyGet); 

        }

        #endregion 


        #region User Account

        [HttpGet]
        public ActionResult UserAccount (Int64 id) {

            Models.Configuration.UserAccountModel model = new Models.Configuration.UserAccountModel (id);

            return View ("~/Views/Configuration/UserAccount.cshtml", model);

        }

        [HttpPost]
        public JsonResult UserAccountSave () {

            JsonResponses.SaveResponse response = new JsonResponses.SaveResponse ();

            Models.Configuration.UserAccountModel model = new Models.Configuration.UserAccountModel (Request.Form);

            response.Result = model.UserAccount.Save ();

            response.Id = model.UserAccount.Id;

            response.SetException (model.Application.LastException);

            return Json (response, JsonRequestBehavior.DenyGet);

        }

        [HttpDelete]
        public ActionResult UserAccountDelete (Int64 id) {

            JsonResponses.BooleanResponse response = new JsonResponses.BooleanResponse ();

            Models.Configuration.UserAccountModel model = new Models.Configuration.UserAccountModel (id);

            response.Result = model.UserAccount.Delete ();

            response.SetException (model.Application.LastException);

            return Json (response, JsonRequestBehavior.DenyGet);

        }

        [HttpGet]
        public JsonResult UserAccountsBySecurityAuthority (Int64 securityAuthorityId) {

            JsonResponses.ObjectCollectionResponse response = new JsonResponses.ObjectCollectionResponse ();


            List<Security.UserAccount> userAccounts = applicationModel.Application.Security.UserAccountsBySecurityAuthority (securityAuthorityId);

            response.Objects = new List<Object> (userAccounts);


            return Json (response, JsonRequestBehavior.AllowGet);

        }

        [HttpGet]
        public JsonResult UsersBySecurityProvider (Int64 securityAuthorityId, String userAccountName) {

            JsonResponses.jqGridDataResponse response = new JsonResponses.jqGridDataResponse (Request.QueryString);


            List<Security.DirectoryEntryHelper> users =  applicationModel.Application.Security.UsersBySecurityProvider (securityAuthorityId, true);

            users = users.FindAll (user => user.Name.ToLower ().Contains (userAccountName.ToLower ()));


            switch (Request.QueryString["sidx"]) {

                case "DisplayName":

                    if (Request.QueryString["sord"] == "desc") {

                        users = users.OrderByDescending (user => user.DisplayName).ToList ();

                    }

                    else {

                        users = users.OrderBy (user => user.DisplayName).ToList ();

                    }

                    break;

                case "DistinguishedName":

                    if (Request.QueryString["sord"] == "desc") {

                        users = users.OrderByDescending (user => user.DistinguishedName).ToList ();

                    }

                    else {

                        users = users.OrderBy (user => user.DistinguishedName).ToList ();

                    }

                    break;

                case "Name":

                default:

                    if (Request.QueryString["sord"] == "desc") {

                        users = users.OrderByDescending (user => user.Name).ToList ();

                    }

                    else {

                        users = users.OrderBy (user => user.Name).ToList ();

                    }

                    break;

            }

            response.RowsByPage (users);


            return Json (response, JsonRequestBehavior.AllowGet);


        }

        #endregion 

    }

}
